﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.EncryptionUtility
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.ServiceModel.Security;
using System.ServiceModel.Security.Tokens;
using System.Xml;

namespace Microsoft.InfoCards
{
  internal sealed class EncryptionUtility
  {
    private EncryptionUtility()
    {
    }

    public static XmlElement EncryptSecurityToken(
      SecurityToken tokenToBeEncrypted,
      X509Certificate2 cert,
      string encryptingAlgorithm,
      string asymmetricKeyWrapAlgorithm,
      ProtocolProfile profile)
    {
      MemoryStream streamToBeEncrypted = new MemoryStream();
      XmlDictionaryWriter dictionaryWriter = XmlDictionaryWriter.CreateDictionaryWriter((XmlWriter) new XmlTextWriter((TextWriter) new StreamWriter((Stream) streamToBeEncrypted)));
      profile.TokenSerializer.WriteToken((XmlWriter) dictionaryWriter, tokenToBeEncrypted);
      dictionaryWriter.Flush();
      streamToBeEncrypted.Seek(0L, SeekOrigin.Begin);
      return EncryptionUtility.EncryptToken(streamToBeEncrypted, cert, encryptingAlgorithm, asymmetricKeyWrapAlgorithm, profile);
    }

    public static XmlElement EncryptSecurityToken(
      XmlElement elem,
      X509Certificate2 cert,
      string encryptingAlgorithm,
      string asymmetricKeyWrapAlgorithm,
      ProtocolProfile profile)
    {
      MemoryStream streamToBeEncrypted = new MemoryStream();
      XmlDictionaryWriter dictionaryWriter = XmlDictionaryWriter.CreateDictionaryWriter((XmlWriter) new XmlTextWriter((TextWriter) new StreamWriter((Stream) streamToBeEncrypted)));
      elem.WriteTo((XmlWriter) dictionaryWriter);
      dictionaryWriter.Flush();
      streamToBeEncrypted.Seek(0L, SeekOrigin.Begin);
      return EncryptionUtility.EncryptToken(streamToBeEncrypted, cert, encryptingAlgorithm, asymmetricKeyWrapAlgorithm, profile);
    }

    private static XmlElement EncryptToken(
      MemoryStream streamToBeEncrypted,
      X509Certificate2 cert,
      string encryptingAlgorithm,
      string asymmetricKeyWrapAlgorithm,
      ProtocolProfile profile)
    {
      InfoCardTrace.ThrowInvalidArgumentConditional(string.IsNullOrEmpty(encryptingAlgorithm), nameof (encryptingAlgorithm));
      InfoCardTrace.ThrowInvalidArgumentConditional(null == cert, nameof (cert));
      SecurityToken wrappingToken = (SecurityToken) new X509SecurityToken(cert, "id");
      SecurityAlgorithmSuite securityAlgorithmSuite1 = SecurityAlgorithmSuite.Default;
      SecurityAlgorithmSuite securityAlgorithmSuite2;
      switch (encryptingAlgorithm)
      {
        case "http://www.w3.org/2001/04/xmlenc#aes128-cbc":
          securityAlgorithmSuite2 = SecurityAlgorithmSuite.Basic128;
          break;
        case "http://www.w3.org/2001/04/xmlenc#aes192-cbc":
          securityAlgorithmSuite2 = SecurityAlgorithmSuite.Basic192;
          break;
        case "http://www.w3.org/2001/04/xmlenc#aes256-cbc":
          securityAlgorithmSuite2 = SecurityAlgorithmSuite.Basic256;
          break;
        case "http://www.w3.org/2001/04/xmlenc#tripledes-cbc":
          securityAlgorithmSuite2 = SecurityAlgorithmSuite.TripleDes;
          break;
        default:
          throw InfoCardTrace.ThrowHelperError((Exception) new TokenCreationException(SR.GetString("UnsupportedEncryptionAlgorithm", (object) encryptingAlgorithm)));
      }
      SecurityKeyIdentifier wrappingTokenReference = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[1]
      {
        (SecurityKeyIdentifierClause) wrappingToken.CreateKeyIdentifierClause<X509ThumbprintKeyIdentifierClause>()
      });
      byte[] numArray = new byte[securityAlgorithmSuite2.DefaultEncryptionKeyDerivationLength / 8];
      new RNGCryptoServiceProvider().GetNonZeroBytes(numArray);
      WrappedKeySecurityToken keySecurityToken = new WrappedKeySecurityToken(string.Empty, numArray, asymmetricKeyWrapAlgorithm, wrappingToken, wrappingTokenReference);
      SecurityKeyIdentifier securityKeyIdentifier = new SecurityKeyIdentifier(new SecurityKeyIdentifierClause[1]
      {
        (SecurityKeyIdentifierClause) new EncryptedKeyIdentifierClause(keySecurityToken.GetWrappedKey(), keySecurityToken.WrappingAlgorithm, keySecurityToken.WrappingTokenReference)
      });
      SymmetricAlgorithm symmetricAlgorithm = ((SymmetricSecurityKey) keySecurityToken.SecurityKeys[0]).GetSymmetricAlgorithm(encryptingAlgorithm);
      EncryptedData encryptedData = new EncryptedData();
      encryptedData.TokenSerializer = (SecurityTokenSerializer) profile.TokenSerializer;
      encryptedData.KeyIdentifier = securityKeyIdentifier;
      encryptedData.EncryptionMethod = encryptingAlgorithm;
      encryptedData.Type = "http://www.w3.org/2001/04/xmlenc#Element";
      encryptedData.SetUpEncryption(symmetricAlgorithm, streamToBeEncrypted.GetBuffer(), 0, Convert.ToInt32(streamToBeEncrypted.Length));
      MemoryStream memoryStream = new MemoryStream();
      XmlDictionaryWriter dictionaryWriter = XmlDictionaryWriter.CreateDictionaryWriter((XmlWriter) new XmlTextWriter((TextWriter) new StreamWriter((Stream) memoryStream)));
      encryptedData.WriteTo((XmlWriter) dictionaryWriter);
      dictionaryWriter.Flush();
      memoryStream.Seek(0L, SeekOrigin.Begin);
      XmlElement xmlElement = (XmlElement) new XmlDocument().ReadNode((XmlReader) Utility.CreateReaderWithQuotas((Stream) memoryStream));
      Array.Clear((Array) streamToBeEncrypted.GetBuffer(), 0, Convert.ToInt32(streamToBeEncrypted.Length));
      Array.Clear((Array) memoryStream.GetBuffer(), 0, Convert.ToInt32(memoryStream.Length));
      streamToBeEncrypted.Close();
      memoryStream.Close();
      return xmlElement;
    }
  }
}
